home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / flying-6.11 / pcon.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-30  |  4.1 KB  |  155 lines

  1. #ifndef _global_h
  2. #    include "global.h"
  3. #endif
  4.  
  5. #ifndef _pcon_h
  6. #    include "pcon.h"
  7. #endif
  8. #ifndef _pocket_h
  9. #    include "pocket.h"
  10. #endif
  11. #ifndef _wall_h
  12. #    include "wall.h"
  13. #endif
  14. #ifndef _graph_h
  15. #    include "graph.h"
  16. #endif
  17.  
  18.  
  19. PocketConnector::~PocketConnector() {
  20.     if (w1)    delete w1;
  21.     if (b1)    delete b1;
  22.     if (w2)    delete w2;
  23.     if (b2)    delete b2;
  24.     if (w3)    delete w3;
  25. }
  26.  
  27. //
  28. // RoundedSegment berechnet eine Wand und den nΣchsten Bogen eines zigzag's.
  29. // Der Startpunkt ist dabei Eingabe-Parameter fⁿr den ersten Punkt und
  30. // gleichzeitig Ausgabe-Parameter fⁿr den genauen Endpunkt des Bogens.
  31. //
  32. // e1, e2    - Punkt 1&2
  33. // st            - Punkt 3 ein/aus
  34. // r            - Radius der Rundung
  35. // w            - erzeugtes Wandobjekt
  36. // a            - erzeugtes Bogenobjekt
  37. //
  38. void PocketConnector::RoundedSegment( const Vec2 &e1, const Vec2 &e2,
  39.         Vec2 *st,    const Real &r,
  40.         Wall **w, StaticArc **a )
  41. {
  42. const Real off=RealZero;
  43. Vec2    para;                                // Hilfsvektoren
  44. Vec2    d1 = (e1-(*st)).Norm1();    // Vektor parallel zur Start-Wand;
  45. Vec2    d2 = (e2-e1).Norm1();        // Vektor parallel zur Zielwand
  46.  
  47. Vec2    o1 = d1.TurnLeft() * r;        // Abstandsvektor 1
  48. Vec2    o2;                                // Abstandsvektor 2
  49.  
  50. Real        off_r;                            // tatsΣchlicher Radius (nach Verschiebung)
  51.  
  52.             o1.Split( d2, ¶ );          // Anteil in Richtung d2
  53.  
  54.             if ( (para.X()*d2.X()<RealZero) || (para.Y()*d2.Y()<RealZero) ) {
  55.                 // nΣchster Bogen nach rechts ...
  56.                         o1   *= -1.0;    // entgegen, dann umkehren
  57.                         o2    = d2.TurnRight() * r;
  58.                         off_r = r-off;
  59.             }
  60.             else {
  61.                 // nΣchster Bogen nach links ...
  62.                         o2    = d2.TurnLeft() * r;
  63.                         off_r = r+off;
  64.             }
  65.  
  66. Real l;        // Faktor fⁿr: p = e1 + l*d2 - o2;
  67.  
  68.         if (Vec2::Solve( e1+o2, d2, (*st)+o1, d1, &l ))        return;
  69.  
  70.         if (l<RealZero) {
  71.             printf( "ZigZag: Ecke: (%f,%f), Radius: %f zu gross (<%f)",
  72.                             (double)e1.X(), (double)e1.Y(), (double)r, (double)(l+r) );
  73.         }
  74.  
  75. Vec2 p  = (*st)+o1 + l*d1;                // Mitte des Kreises
  76. Vec2 p1 = p-o1;                                // Endpunkt erstes Segment
  77. Vec2 p2 = p-o2;                                // Startpunkt zweites Segment
  78. double a1, a2;                                    // Winkel zu den beiden Segmentpunkten
  79. double ang;                                        // Winkel-Differenz
  80.  
  81. Vec2    from = (*st)-d1.TurnLeft()*off;
  82. Vec2    to   = p1-d1.TurnLeft()*off;
  83.         *w = new Wall( from.X(), from.Y(), to.X(), to.Y() );
  84.  
  85.         if (off_r>RealZero) {
  86.             a1 = p.AngleDeg( p-o1 );
  87.             a2 = p.AngleDeg( p-o2 );
  88.             ang = a2-a1;
  89.             if (ang<0)    ang+=360.;
  90.             if (ang>180)    *a = new OuterArc( p.X(), p.Y(), off_r, a2, 360-ang );
  91.             else                *a = new OuterArc( p.X(), p.Y(), off_r, a1, ang );
  92.         }
  93.         else                    *a = new StaticBall( p.X(), p.Y(), 0.0 );
  94.  
  95.         *st = p2;                                // Startpunkt zurueckgeben
  96. }
  97.  
  98. //
  99. // Analog zur pocket_connect-Routine aus creator.C wurde die Init-Methode
  100. // des PocketConnector's aufgebaut. Allerdings werden keine gerundeten
  101. // Ecken erzeugt.
  102. //
  103. //              start                          end
  104. //          /.\                            /
  105. //        s_ang/   \                          /
  106. //             /     \                        /
  107. //          p1---> --\----------------------/----  p2
  108. //            |  dir   \angle               /
  109. //        off|             \                  /
  110. //            v                ----------------
  111. //                          egde1           edge2
  112. //
  113.  
  114. #define    TANGENTIAL
  115.  
  116.  
  117. int PocketConnector::Init( const Pocket &p1, const Real &angle1,
  118.                              const Pocket &p2, const Real &angle2,
  119.                              const Real &cushion, const Real &rad )
  120. {
  121. Real        ls;                                 // Ergebnis des Gleichungssystems
  122. Vec2    dir    =(p2.P()-p1.P()).Norm1();        // Richtungsvektor
  123. Vec2    off    = dir.TurnLeft()*cushion;        // Abstand der Wand
  124.  
  125. Vec2    s_ang = dir.TurnAngleDeg(angle1);    // Richtungsvektor zum Startpunkt
  126.  
  127. #ifdef TANGENTIAL
  128. Vec2    start = p1.P()+s_ang*p1.R();            // Startpunkt
  129. #else
  130. Vec2    start = p1.P() + dir*p1.R();
  131. #endif
  132.  
  133.         if (Vec2::Solve( start, s_ang.TurnRight(), p1.P()+off, dir, &ls ))    return 1;
  134. Vec2    edge1 = p1.P()+off+dir*ls;
  135.  
  136.  
  137. Vec2    s_end = Vec2(-dir).TurnAngleDeg(-angle2);// Richtungsvektor zum Endpunkt
  138.  
  139. #ifdef TANGENTIAL
  140. Vec2    end   = p2.P()+s_end*p2.R();            // Endpunkt
  141. #else
  142. Vec2    end    = p2.P() - dir*p2.R();
  143. #endif
  144.  
  145.         if (Vec2::Solve( end, s_end.TurnLeft(), p2.P()+off, dir, &ls ))    return 1;
  146. Vec2    edge2 = p2.P()+off+dir*ls;
  147.  
  148.     RoundedSegment( edge1, edge2, &start, rad, &w1, &b1 );
  149.     RoundedSegment( edge2,   end, &start, rad, &w2, &b2 );
  150.     w3 = new Wall( start, end );
  151.  
  152.     return 0;
  153. }
  154.  
  155.